package cn.com.coding.common.log;

import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.CodeSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * sercice 层切面输出日志
 *
 * @author mxz
 */
@Aspect
@Component
public class ServiceLogAspect {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 定义控制器切入点
     */
    @Pointcut("@within(org.springframework.stereotype.Service)")
    public void servicePointcut() {
    }

    /**
     * 进入控制器方法之前的切入点
     */
    @Before("servicePointcut()")
    public void before(JoinPoint jp) {
        String params = this.writeParams(jp);
        logger.info("entry service - [{}.{}()] [params: {}]",
                jp.getTarget().getClass().getName(), jp.getSignature().getName(), params);
    }

    /**
     * 控制器方法执行之后
     */
    @After("servicePointcut()")
    public void after(JoinPoint jp) {
        logger.info("exit service with {}.{}()",
                jp.getTarget().getClass().getName(), jp.getSignature().getName());
    }

    public String writeParams(JoinPoint jp) {
        String[] names = ((CodeSignature) jp.getSignature())
                .getParameterNames();
        Object[] args = jp.getArgs();

        if (ArrayUtils.isEmpty(names)) {
            return "";
        }

        StringBuilder sb = new StringBuilder("Arguments: ");
        for (int i = 0; i < names.length; i++) {
            sb.append(names[i] + " = " + args[i] + ",");
        }
        return sb.toString();
    }
}
